
#ifndef _SCREENMANAGER
#define _SCREENMANAGER

#include <map>
#include <CEGUI/CEGUI.h>
#include <OIS/OIS.h>
#include <OgreCEGUIRenderer.h>
#include <OgreSingleton.h>
#include "GUI/Screens.h"

//struct eqstr
//{
//  bool operator()(const String  s1,const String  s2) const
//  {
//    return strcmp(s1, s2) < 0;
//  }
//};
typedef std::pair <String , Screen*> ScreenName;
class ScreenManager  :public Ogre::Singleton<ScreenManager>
{
public:
	ScreenManager(){}
	~ScreenManager()
	{
		for (std::map <String ,Screen*>::iterator itr=mScreens.begin();itr!=mScreens.end();itr++)
			delete itr->second;
		mScreens.clear();
	}
	void addScreen(String name, Screen* pScreen)
	{
		mScreens.insert(ScreenName(name,pScreen));
		if(mScreens.size() == 1)
			mCurrentScreen = mScreens.begin();
	}
	void removeScreen(String name)
	{
		mScreens.erase(name);
	}
	Screen *getScreen(String screen)
	{
		return mScreens.find(screen)->second;
	}
	Screen *getCurrentScreen()
	{
		return mCurrentScreen->second;
	}
	void setScreen(String name)
	{
		mCurrentScreen->second->unSubscribeEvents();
		mCurrentScreen = mScreens.find(name);
		mCurrentScreen->second->showLayout();

	}
	static ScreenManager& getSingleton(void);
    static ScreenManager* getSingletonPtr(void);
private:
	std::map <String ,Screen*>::const_iterator mCurrentScreen;
	std::map<String ,Screen*> mScreens;  
};
template<> ScreenManager* Ogre::Singleton<ScreenManager>::ms_Singleton = 0;
ScreenManager* ScreenManager::getSingletonPtr(void)
{
    return ms_Singleton;
}
ScreenManager& ScreenManager::getSingleton(void)
{  
    assert( ms_Singleton );  return ( *ms_Singleton );  
}

class ScreenListener :public Ogre::FrameListener, public OIS::MouseListener, public OIS::KeyListener, Ogre::Singleton<ScreenListener>
{
public:
	ScreenListener(OIS::Keyboard *keyboard, OIS::Mouse *mouse):mKeyboard(keyboard),mMouse(mouse)
	{	
		//mContinue=true;
		mMouse->setEventCallback(this);
		mKeyboard->setEventCallback(this);
	}
	bool frameStarted(const Ogre::FrameEvent &evt)
    {
        mKeyboard->capture();
        mMouse->capture();
		String nextScreenName = ScreenManager::getSingletonPtr()->getCurrentScreen()->getNextScreenName();
		if (nextScreenName.compare("")!=0)
			ScreenManager::getSingletonPtr()->setScreen(nextScreenName);
		
		return ScreenManager::getSingletonPtr()->getCurrentScreen()->update(evt);
        //return mContinue;
    }

    // MouseListener
    bool mouseMoved(const OIS::MouseEvent &arg)
    {
		GUIManager::getSingletonPtr()->GUImouseMoved(arg);
		ScreenManager::getSingletonPtr()->getCurrentScreen()->mouseMoved(arg);
        return true;
    }

    bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
		GUIManager::getSingletonPtr()->GUImousePressed(arg,id);
		ScreenManager::getSingletonPtr()->getCurrentScreen()->mousePressed(arg,id);
        return true;
    }

    bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
		GUIManager::getSingletonPtr()->GUImouseReleased(arg,id);
		ScreenManager::getSingletonPtr()->getCurrentScreen()->mouseReleased(arg,id);
        return true;
    }

    // KeyListener
    bool keyPressed(const OIS::KeyEvent &arg)
    {
		GUIManager::getSingletonPtr()->GUIkeyPressed(arg);
		ScreenManager::getSingletonPtr()->getCurrentScreen()->keyPressed(arg);
        return true;
    }

    bool keyReleased(const OIS::KeyEvent &arg)
    {
		GUIManager::getSingletonPtr()->GUIkeyReleased(arg);
		ScreenManager::getSingletonPtr()->getCurrentScreen()->keyReleased(arg);
        return true;
    }

	static ScreenListener& getSingleton(void);
    static ScreenListener* getSingletonPtr(void);
protected:
	//bool mContinue;
	OIS::Keyboard *mKeyboard;
	OIS::Mouse *mMouse;
};
template<> ScreenListener* Ogre::Singleton<ScreenListener>::ms_Singleton = 0;
ScreenListener* ScreenListener::getSingletonPtr(void)
{
    return ms_Singleton;
}
ScreenListener& ScreenListener::getSingleton(void)
{  
    assert( ms_Singleton );  return ( *ms_Singleton );  
}

#endif